#pragma once
#include "Runtime/BattleFirePrefix.h"
#include "CGIAccess.h"
#ifdef ALICE_VULKAN
#ifdef _WIN32
#define VK_USE_PLATFORM_WIN32_KHR
#endif
#include "vulkan/vulkan.h"
#if VK_HEADER_VERSION >= 141
	//workaround for removed defines in sdk 141
	#define VK_DESCRIPTOR_TYPE_BEGIN_RANGE (VK_DESCRIPTOR_TYPE_SAMPLER)
	#define VK_DESCRIPTOR_TYPE_END_RANGE (VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT)
	#define VK_DESCRIPTOR_TYPE_RANGE_SIZE (VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT - VK_DESCRIPTOR_TYPE_SAMPLER + 1)
	#define VK_IMAGE_VIEW_TYPE_RANGE_SIZE (VK_IMAGE_VIEW_TYPE_CUBE_ARRAY - VK_IMAGE_VIEW_TYPE_1D + 1)
	#define VK_DYNAMIC_STATE_BEGIN_RANGE (VK_DYNAMIC_STATE_VIEWPORT)
	#define VK_DYNAMIC_STATE_END_RANGE (VK_DYNAMIC_STATE_STENCIL_REFERENCE)
	#define VK_DYNAMIC_STATE_RANGE_SIZE (VK_DYNAMIC_STATE_STENCIL_REFERENCE - VK_DYNAMIC_STATE_VIEWPORT + 1)
	#define VK_FORMAT_RANGE_SIZE (VK_FORMAT_ASTC_12x12_SRGB_BLOCK - VK_FORMAT_UNDEFINED + 1)
	template<typename BitsType>
	constexpr bool VKHasAllFlags(VkFlags Flags, BitsType Contains)
	{
		return (Flags & Contains) == Contains;
	}

	template<typename BitsType>
	constexpr bool VKHasAnyFlags(VkFlags Flags, BitsType Contains)
	{
		return (Flags & Contains) != 0;
	}
#endif
#define VERIFYVULKANRESULT(x) x
template< class T >
static FORCEINLINE void ZeroVulkanStruct(T& Struct, int32 VkStructureType)
{
	// Horrible way to coerce the compiler to not have to know what T::sType is so we can have this header not have to include vulkan.h
	(int32&)Struct.sType = VkStructureType;
	memset(((uint8*)&Struct) + sizeof(VkStructureType), 0,sizeof(T) - sizeof(VkStructureType));
}
#endif
/** Alignment of the shader parameters struct is required to be 16-byte boundaries. */
#define SHADER_PARAMETER_STRUCT_ALIGNMENT 16

/** The alignment in bytes between elements of array shader parameters. */
#define SHADER_PARAMETER_ARRAY_ELEMENT_ALIGNMENT 16

namespace Alice
{
	/** The maximum number of vertex elements which can be used by a vertex declaration. */
	enum
	{
		MaxVertexElementCount = 17,
		MaxVertexElementCount_NumBits = 5,
	};
	/** The number of render-targets that may be simultaneously written to. */
	enum
	{
		MaxSimultaneousRenderTargets = 8,
		MaxSimultaneousRenderTargets_NumBits = 3,
	};
	/** @warning: update *LegacyShaderPlatform* when the below changes */
	enum EShaderPlatform : uint16
	{
		SP_PCD3D_SM5 = 0,
		SP_METAL = 11,
		SP_METAL_MRT = 12,
		SP_PCD3D_ES3_1 = 14,
		SP_OPENGL_PCES3_1 = 15,
		SP_METAL_SM5 = 16,
		SP_VULKAN_PCES3_1 = 17,
		SP_VULKAN_SM5 = 20,
		SP_VULKAN_ES3_1_ANDROID = 21,
		SP_METAL_MACES3_1 = 22,
		SP_OPENGL_ES3_1_ANDROID = 24,
		SP_METAL_MRT_MAC = 27,
		SP_METAL_TVOS = 30,
		SP_METAL_MRT_TVOS = 31,
		/**********************************************************************************/
		/* !! Do not add any new platforms here. Add them below SP_StaticPlatform_Last !! */
		/**********************************************************************************/

		//---------------------------------------------------------------------------------
		/** Pre-allocated block of shader platform enum values for platform extensions */
	#define DDPI_NUM_STATIC_SHADER_PLATFORMS 16
		SP_StaticPlatform_First = 32,

		// Pull in the extra shader platform definitions from platform extensions.
		// @todo - when we remove EShaderPlatform, fix up the shader platforms defined in UEBuild[Platform].cs files.
	#ifdef DDPI_EXTRA_SHADERPLATFORMS
		DDPI_EXTRA_SHADERPLATFORMS
	#endif

		SP_StaticPlatform_Last = (SP_StaticPlatform_First + DDPI_NUM_STATIC_SHADER_PLATFORMS - 1),

		//  Add new platforms below this line, starting from (SP_StaticPlatform_Last + 1)
		//---------------------------------------------------------------------------------
		SP_VULKAN_SM5_ANDROID = SP_StaticPlatform_Last + 1,
		SP_PCD3D_SM6          = SP_StaticPlatform_Last + 2,
		SP_VULKAN_SM6         = SP_StaticPlatform_Last + 4,
		SP_METAL_SM6          = SP_StaticPlatform_Last + 5,
		SP_METAL_SIM          = SP_StaticPlatform_Last + 6,

		SP_CUSTOM_PLATFORM_FIRST,
		SP_CUSTOM_PLATFORM_LAST = (SP_CUSTOM_PLATFORM_FIRST + 100),

		SP_NumPlatforms,
		SP_NumBits = 16,
	};
		
	enum class ERHIPipeline : uint8
	{
		Graphics = 1 << 0,
		AsyncCompute = 1 << 1,

		None = 0,
		All = Graphics | AsyncCompute,
		Num = 2
	};
	ENUM_CLASS_FLAGS(ERHIPipeline)
	enum class EPixelFormat : uint8
	{
		PF_Unknown              =0,
		PF_A32B32G32R32F        =1,
		PF_B8G8R8A8             =2,
		PF_G8                   =3, // G8  means Gray/Grey , not Green , typically actually uses a red format with replication of R to RGB
		PF_G16                  =4, // G16 means Gray/Grey like G8
		PF_DXT1                 =5,
		PF_DXT3                 =6,
		PF_DXT5                 =7,
		PF_UYVY                 =8,
		PF_FloatRGB             =9,  // FloatRGB == PF_FloatR11G11B10 , NOT 16F usually, but varies
		PF_FloatRGBA            =10, // RGBA16F
		PF_DepthStencil         =11,
		PF_ShadowDepth          =12,
		PF_R32_FLOAT            =13,
		PF_G16R16               =14,
		PF_G16R16F              =15,
		PF_G16R16F_FILTER       =16,
		PF_G32R32F              =17,
		PF_A2B10G10R10          =18,
		PF_A16B16G16R16         =19,
		PF_D24                  =20,
		PF_R16F                 =21,
		PF_R16F_FILTER          =22,
		PF_BC5                  =23,
		PF_V8U8                 =24,
		PF_A1                   =25,
		PF_FloatR11G11B10       =26,
		PF_A8                   =27,
		PF_R32_UINT             =28,
		PF_R32_SINT             =29,
		PF_PVRTC2               =30,
		PF_PVRTC4               =31,
		PF_R16_UINT             =32,
		PF_R16_SINT             =33,
		PF_R16G16B16A16_UINT    =34,
		PF_R16G16B16A16_SINT    =35,
		PF_R5G6B5_UNORM         =36,
		PF_R8G8B8A8             =37,
		PF_A8R8G8B8				=38,	// Only used for legacy loading; do NOT use!
		PF_BC4					=39,
		PF_R8G8                 =40,	
		PF_ATC_RGB				=41,	// Unsupported Format
		PF_ATC_RGBA_E			=42,	// Unsupported Format
		PF_ATC_RGBA_I			=43,	// Unsupported Format
		PF_X24_G8				=44,	// Used for creating SRVs to alias a DepthStencil buffer to read Stencil. Don't use for creating textures.
		PF_ETC1					=45,	// Unsupported Format
		PF_ETC2_RGB				=46,
		PF_ETC2_RGBA			=47,
		PF_R32G32B32A32_UINT	=48,
		PF_R16G16_UINT			=49,
		PF_ASTC_4x4             =50,	// 8.00 bpp
		PF_ASTC_6x6             =51,	// 3.56 bpp
		PF_ASTC_8x8             =52,	// 2.00 bpp
		PF_ASTC_10x10           =53,	// 1.28 bpp
		PF_ASTC_12x12           =54,	// 0.89 bpp
		PF_BC6H					=55,
		PF_BC7					=56,
		PF_R8_UINT				=57,
		PF_L8					=58,
		PF_XGXR8				=59,
		PF_R8G8B8A8_UINT		=60,
		PF_R8G8B8A8_SNORM		=61,
		PF_R16G16B16A16_UNORM	=62,
		PF_R16G16B16A16_SNORM	=63,
		PF_PLATFORM_HDR_0		=64,
		PF_PLATFORM_HDR_1		=65,	// Reserved.
		PF_PLATFORM_HDR_2		=66,	// Reserved.
		PF_NV12					=67,
		PF_R32G32_UINT          =68,
		PF_ETC2_R11_EAC			=69,
		PF_ETC2_RG11_EAC		=70,
		PF_R8		            =71,
		PF_B5G5R5A1_UNORM       =72,
		PF_ASTC_4x4_HDR         =73,	
		PF_ASTC_6x6_HDR         =74,	
		PF_ASTC_8x8_HDR         =75,	
		PF_ASTC_10x10_HDR       =76,	
		PF_ASTC_12x12_HDR       =77,
		PF_G16R16_SNORM			=78,
		PF_R8G8_UINT			=79,
		PF_R32G32B32_UINT		=80,
		PF_R32G32B32_SINT		=81,
		PF_R32G32B32F			=82,
		PF_R8_SINT				=83,	
		PF_R64_UINT				=84,
		PF_R9G9B9EXP5			=85,
		PF_P010					=86,
		PF_ASTC_4x4_NORM_RG		=87, // RG format stored in LA endpoints for better precision (requires RHI support for texture swizzle)
		PF_ASTC_6x6_NORM_RG		=88,	
		PF_ASTC_8x8_NORM_RG		=89,	
		PF_ASTC_10x10_NORM_RG	=90,	
		PF_ASTC_12x12_NORM_RG	=91,	
		PF_R16G16_SINT			=92,
		PF_NUM					=93,
	};
	// EPixelFormat is currently used interchangably with uint8, and most call sites taking a uint8
	// should be updated to take an EPixelFormat instead, but in the interim this allows fixing
	// type conversion warnings
	#define ALICE_PIXELFORMAT_TO_UINT8(argument) static_cast<uint8>(argument)
    enum class ECGIInterfaceType
    {
        Null,
        D3D11,
        D3D12,
        Vulkan,
        Metal,
        OpenGL
    };
    enum class ECGIFeatureSupport : uint8
    {
        // The CGI feature is completely unavailable at runtime
        Unsupported,
        // The CGI feature can be available at runtime based on hardware or driver
        RuntimeDependent,
        // The CGI feature is guaranteed to be available at runtime.
        RuntimeGuaranteed,
        Num,
        NumBits = 2,
    };
    enum class ECGIBindlessSupport : uint8
    {
        Unsupported,
        RayTracingOnly,
        AllShaderTypes,
        NumBits = 2
    };
    
    enum EShaderStage : uint8
    {
        SS_Vertex				= 0,
        //mesh shader start
        SS_Mesh					= 1,
        SS_Amplification		= 2,
        //mesh shader end
        SS_Pixel				= 3,
        SS_Geometry				= 4,
        SS_Compute				= 5,
        SS_RayGen				= 6,
        SS_RayMiss				= 7,
        SS_RayHitGroup			= 8,
        SS_RayCallable			= 9,
        SS_WorkGraphRoot		= 10,
        SS_WorkGraphComputeNode	= 11,

        SS_NumStages	= 12,

        // Number of standard shader frequencies for graphics pipeline (excluding compute)
        SS_NumGraphicsStages = 5,

        // Number of standard shader frequencies (including compute)
        SS_NumStandardStages = 6,

        SS_NumBits			= 4,
    };
    namespace ECGIShadingPath
    {
        enum Type : int
        {
            Deferred,
            Forward,
            Mobile,
            Num
        };
    }
    enum ESamplerFilter
    {
        SF_Point,
        SF_Bilinear,
        SF_Trilinear,
        SF_AnisotropicPoint,
        SF_AnisotropicLinear,

        ESamplerFilter_Num,
        ESamplerFilter_NumBits = 3,
    };
    enum ESamplerAddressMode
    {
        AM_Wrap,
        AM_Clamp,
        AM_Mirror,
        /** Not supported on all platforms */
        AM_Border,

        ESamplerAddressMode_Num,
        ESamplerAddressMode_NumBits = 2,
    };
    enum ESamplerCompareFunction
    {
        SCF_Never,
        SCF_Less
    };

    enum ERasterizerFillMode
    {
        FM_Point,
        FM_Wireframe,
        FM_Solid,

        ERasterizerFillMode_Num,
        ERasterizerFillMode_NumBits = 2,
    };
    enum ERasterizerCullMode
    {
        CM_None,
        CM_CW,
        CM_CCW,

        ERasterizerCullMode_Num,
        ERasterizerCullMode_NumBits = 2,
    };
    enum EColorWriteMask
    {
        CW_RED   = 0x01,
        CW_GREEN = 0x02,
        CW_BLUE  = 0x04,
        CW_ALPHA = 0x08,

        CW_NONE  = 0,
        CW_RGB   = CW_RED | CW_GREEN | CW_BLUE,
        CW_RGBA  = CW_RED | CW_GREEN | CW_BLUE | CW_ALPHA,
        CW_RG    = CW_RED | CW_GREEN,
        CW_BA    = CW_BLUE | CW_ALPHA,

        EColorWriteMask_NumBits = 4,
    };
    enum ECompareFunction
    {
        CF_Less,
        CF_LessEqual,
        CF_Greater,
        CF_GreaterEqual,
        CF_Equal,
        CF_NotEqual,
        CF_Never,
        CF_Always,

        ECompareFunction_Num,
        ECompareFunction_NumBits = 3,

        // Utility enumerations
        CF_DepthNearOrEqual		= CF_LessEqual,
        CF_DepthNear			= CF_Less,
        CF_DepthFartherOrEqual	= CF_GreaterEqual,
        CF_DepthFarther			= CF_Greater,
    };
    enum EStencilMask
    {
        SM_Default,
        SM_255,
        SM_1,
        SM_2,
        SM_4,
        SM_8,
        SM_16,
        SM_32,
        SM_64,
        SM_128,
        SM_Count
    };

    enum EStencilOp
    {
        SO_Keep,
        SO_Zero,
        SO_Replace,
        SO_SaturatedIncrement,
        SO_SaturatedDecrement,
        SO_Invert,
        SO_Increment,
        SO_Decrement,

        EStencilOp_Num,
        EStencilOp_NumBits = 3,
    };
    enum EBlendOperation
    {
        BO_Add,
        BO_Subtract,
        BO_Min,
        BO_Max,
        BO_ReverseSubtract,

        EBlendOperation_Num,
        EBlendOperation_NumBits = 3,
    };
    enum EBlendFactor
    {
        BF_Zero,
        BF_One,
        BF_SourceColor,
        BF_InverseSourceColor,
        BF_SourceAlpha,
        BF_InverseSourceAlpha,
        BF_DestAlpha,
        BF_InverseDestAlpha,
        BF_DestColor,
        BF_InverseDestColor,
        BF_ConstantBlendFactor,
        BF_InverseConstantBlendFactor,
        BF_Source1Color,
        BF_InverseSource1Color,
        BF_Source1Alpha,
        BF_InverseSource1Alpha,

        EBlendFactor_Num,
        EBlendFactor_NumBits = 4,
    };
    enum EVertexElementType
    {
        VET_None,
        VET_Float1,
        VET_Float2,
        VET_Float3,
        VET_Float4,
        VET_PackedNormal,	// FPackedNormal
        VET_UByte4,
        VET_UByte4N,
        VET_Color,
        VET_Short2,
        VET_Short4,
        VET_Short2N,		// 16 bit word normalized to (value/32767.0,value/32767.0,0,0,1)
        VET_Half2,			// 16 bit float using 1 bit sign, 5 bit exponent, 10 bit mantissa 
        VET_Half4,
        VET_Short4N,		// 4 X 16 bit word, normalized 
        VET_UShort2,
        VET_UShort4,
        VET_UShort2N,		// 16 bit word normalized to (value/65535.0,value/65535.0,0,0,1)
        VET_UShort4N,		// 4 X 16 bit word unsigned, normalized 
        VET_URGB10A2N,		// 10 bit r, g, b and 2 bit a normalized to (value/1023.0f, value/1023.0f, value/1023.0f, value/3.0f)
        VET_UInt,
        VET_MAX,

        VET_NumBits = 5,
    };
    enum ECubeFace : uint32
    {
        CubeFace_PosX = 0,
        CubeFace_NegX,
        CubeFace_PosY,
        CubeFace_NegY,
        CubeFace_PosZ,
        CubeFace_NegZ,
        CubeFace_MAX
    };

    enum EUniformBufferUsage
    {
        // the uniform buffer is temporary, used for a single draw call then discarded
        UniformBuffer_SingleDraw = 0,
        // the uniform buffer is used for multiple draw calls but only for the current frame
        UniformBuffer_SingleFrame,
        // the uniform buffer is used for multiple draw calls, possibly across multiple frames
        UniformBuffer_MultiFrame,
    };
    enum class EShaderCodeResourceBindingType : uint8
    {
        Invalid,

        SamplerState,

        // Texture1D: not used in the renderer.
        // Texture1DArray: not used in the renderer.
        Texture2D,
        Texture2DArray,
        Texture2DMS,
        Texture3D,
        // Texture3DArray: not used in the renderer.
        TextureCube,
        TextureCubeArray,
        TextureMetadata,

        Buffer,
        StructuredBuffer,
        ByteAddressBuffer,
        RaytracingAccelerationStructure,

        // RWTexture1D: not used in the renderer.
        // RWTexture1DArray: not used in the renderer.
        RWTexture2D,
        RWTexture2DArray,
        RWTexture3D,
        // RWTexture3DArray: not used in the renderer.
        RWTextureCube,
        // RWTextureCubeArray: not used in the renderer.
        RWTextureMetadata,

        RWBuffer,
        RWStructuredBuffer,
        RWByteAddressBuffer,

        RasterizerOrderedTexture2D,

        ResourceCollection,

        MAX
    };
    enum EUniformBufferBaseType : uint8
    {
        UBMT_INVALID,

        // Invalid type when trying to use bool, to have explicit error message to programmer on why
        // they shouldn't use bool in shader parameter structures.
        UBMT_BOOL,

        // Parameter types.
        UBMT_INT32,
        UBMT_UINT32,
        UBMT_FLOAT32,

        // CGI resources not tracked by render graph.
        UBMT_TEXTURE,
        UBMT_SRV,
        UBMT_UAV,
        UBMT_SAMPLER,

        // Resources tracked by render graph.
        UBMT_RDG_TEXTURE,
        UBMT_RDG_TEXTURE_ACCESS,
        UBMT_RDG_TEXTURE_ACCESS_ARRAY,
        UBMT_RDG_TEXTURE_SRV,
        UBMT_RDG_TEXTURE_NON_PIXEL_SRV,
        UBMT_RDG_TEXTURE_UAV,
        UBMT_RDG_BUFFER_ACCESS,
        UBMT_RDG_BUFFER_ACCESS_ARRAY,
        UBMT_RDG_BUFFER_SRV,
        UBMT_RDG_BUFFER_UAV,
        UBMT_RDG_UNIFORM_BUFFER,

        // Nested structure.
        UBMT_NESTED_STRUCT,

        // Structure that is nested on C++ side, but included on shader side.
        UBMT_INCLUDED_STRUCT,

        // GPU Indirection reference of struct, like is currently named Uniform buffer.
        UBMT_REFERENCED_STRUCT,

        // Structure dedicated to setup render targets for a rasterizer pass.
        UBMT_RENDER_TARGET_BINDING_SLOTS,

        UBMT_RESOURCE_COLLECTION,

        EUniformBufferBaseType_Num,
        EUniformBufferBaseType_NumBits = 5,
    };
    /** The list of flags declaring which binding models are allowed for a uniform buffer layout. */
    enum class EUniformBufferBindingFlags : uint8
    {
        /** If set, the uniform buffer can be bound as an CGI shader parameter on an CGI shader (i.e. CGISetShaderUniformBuffer). */
        Shader = 1 << 0,

        /** If set, the uniform buffer can be bound globally through a static slot (i.e. CGISetStaticUniformBuffers). */
        Static = 1 << 1,

        /** If set, the uniform buffer can be bound globally or per-shader, depending on the use case. Only one binding model should be
         *  used at a time, and CGI validation will emit an error if both are used for a particular uniform buffer at the same time. This
         *  is designed for difficult cases where a fixed single binding model would produce an unnecessary maintenance burden. Using this
         *  disables some CGI validation errors for global bindings, so use with care.
         */
        StaticAndShader = Static | Shader
    };
    /** Flags for Uniform Buffers */
    enum class ECGIUniformBufferFlags : uint8
    {
        None                    = 0,

        /** Whether to force a real uniform buffer when using emulated uniform buffers */
        NoEmulatedUniformBuffer = 1 << 0,

        /** Signals if the uniform buffer members need to be included in shader reflection */
        NeedsReflectedMembers   = 1 << 1,

        /** Whether this layout may contain non-render-graph outputs (e.g. CGI UAVs). */
        HasNonGraphOutputs      = 1 << 2,

        /** This struct is a view into uniform buffer object, on platforms that support UBO */
        UniformView             = 1 << 3,
    };
    enum EResourceLockMode
    {
        RLM_ReadOnly,
        RLM_WriteOnly,
        RLM_WriteOnly_NoOverwrite,
        RLM_Num
    };

    /** limited to 8 types in FReadSurfaceDataFlags */
    // RCM_UNorm is the default
    // RCM_MinMax means "leave the values alone" and is recommended as what you should use
    // RCM_SNorm and RCM_MinMaxNorm seem to be unsupported
    enum ERangeCompressionMode
    {
        // 0 .. 1
        RCM_UNorm, // if you read values that go outside [0,1], they are scaled to fit inside [0,1]
        // -1 .. 1
        RCM_SNorm,
        // 0 .. 1 unless there are smaller values than 0 or bigger values than 1, then the range is extended to the minimum or the maximum of the values
        RCM_MinMaxNorm,
        // minimum .. maximum (each channel independent)
        RCM_MinMax, // read values without changing them
    };
    enum class EPrimitiveTopologyType : uint8
    {
        Triangle,
        Patch,
        Line,
        Point,
        //Quad,

        Num,
        NumBits = 2,
    };
    enum EPrimitiveType
    {
        // Topology that defines a triangle N with 3 vertex extremities: 3*N+0, 3*N+1, 3*N+2.
        PT_TriangleList,

        // Topology that defines a triangle N with 3 vertex extremities: N+0, N+1, N+2.
        PT_TriangleStrip,

        // Topology that defines a line with 2 vertex extremities: 2*N+0, 2*N+1.
        PT_LineList,

        // Topology that defines a quad N with 4 vertex extremities: 4*N+0, 4*N+1, 4*N+2, 4*N+3.
        // Supported only if GCGISupportsQuadTopology == true.
        PT_QuadList,

        // Topology that defines a point N with a single vertex N.
        PT_PointList,

        // Topology that defines a screen aligned rectangle N with only 3 vertex corners:
        //    3*N + 0 is upper-left corner,
        //    3*N + 1 is upper-right corner,
        //    3*N + 2 is the lower-left corner.
        // Supported only if GCGISupportsRectTopology == true.
        PT_RectList,

        PT_Num,
        PT_NumBits = 3
    };
    enum EVRSAxisShadingRate : uint8
	{
		VRSASR_1X = 0x0,
		VRSASR_2X = 0x1,
		VRSASR_4X = 0x2,
	};

	enum EVRSShadingRate : uint8
	{
		VRSSR_1x1  = (VRSASR_1X << 2) + VRSASR_1X,
		VRSSR_1x2  = (VRSASR_1X << 2) + VRSASR_2X,
		VRSSR_2x1  = (VRSASR_2X << 2) + VRSASR_1X,
		VRSSR_2x2  = (VRSASR_2X << 2) + VRSASR_2X,
		VRSSR_2x4  = (VRSASR_2X << 2) + VRSASR_4X,
		VRSSR_4x2  = (VRSASR_4X << 2) + VRSASR_2X,
		VRSSR_4x4  = (VRSASR_4X << 2) + VRSASR_4X,
		
		VRSSR_Last  = VRSSR_4x4
	};

	enum EVRSRateCombiner : uint8
	{
		VRSRB_Passthrough,
		VRSRB_Override,
		VRSRB_Min,
		VRSRB_Max,
		VRSRB_Sum,
	};

	enum EVRSImageDataType : uint8
	{
		VRSImage_NotSupported,		// Image-based Variable Rate Shading is not supported on the current device/platform.
		VRSImage_Palette,			// Image-based VRS uses a palette of discrete, enumerated values to describe shading rate per tile.
		VRSImage_Fractional,		// Image-based VRS uses a floating point value to describe shading rate in X/Y (e.g. 1.0f is full rate, 0.5f is half-rate, 0.25f is 1/4 rate, etc).
	};

	/**
	 *	Resource usage flags - for vertex and index buffers.
	 */
	enum class EBufferUsageFlags : uint32
	{
		None                    = 0,

		/** The buffer will be written to once. */
		Static                  = 1 << 0,

		/** The buffer will be written to occasionally, GPU read only, CPU write only.  The data lifetime is until the next update, or the buffer is destroyed. */
		Dynamic                 = 1 << 1,

		/** The buffer's data will have a lifetime of one frame.  It MUST be written to each frame, or a new one created each frame. */
		Volatile                = 1 << 2,

		/** Allows an unordered access view to be created for the buffer. */
		UnorderedAccess         = 1 << 3,

		/** Create a byte address buffer, which is basically a structured buffer with a uint32 type. */
		ByteAddressBuffer       = 1 << 4,

		/** Buffer that the GPU will use as a source for a copy. */
		SourceCopy              = 1 << 5,

		UNUSED_BIT_6            = 1 << 6,

		/** Create a buffer which contains the arguments used by DispatchIndirect or DrawIndirect. */
		DrawIndirect            = 1 << 7,

		/** 
		 * Create a buffer that can be bound as a shader resource. 
		 * This is only needed for buffer types which wouldn't ordinarily be used as a shader resource, like a vertex buffer.
		 */
		ShaderResource          = 1 << 8,

		/** Request that this buffer is directly CPU accessible. */
		KeepCPUAccessible       = 1 << 9,

		/** Buffer should go in fast vram (hint only). Requires BUF_Transient */
		FastVRAM                = 1 << 10,

		/** Buffer is used by NNE.  DirectML requires NNE resources to be in single device memory heaps when multi-GPU is active. */
		NNE						= 1 << 11,

		/** Create a buffer that can be shared with an external CGI or process. */
		Shared                  = 1 << 12,

		/**
		 * Buffer contains opaque ray tracing acceleration structure data.
		 * Resources with this flag can't be bound directly to any shader stage and only can be used with ray tracing APIs.
		 * This flag is mutually exclusive with all other buffer flags except Static and ReservedResource.
		*/
		AccelerationStructure   = 1 << 13,

		VertexBuffer            = 1 << 14,
		IndexBuffer             = 1 << 15,
		StructuredBuffer        = 1 << 16,

		/** Buffer memory is allocated independently for multiple GPUs, rather than shared via driver aliasing */
		MultiGPUAllocate		= 1 << 17,

		/**
		 * Tells the render graph to not bother transferring across GPUs in multi-GPU scenarios.  Useful for cases where
		 * a buffer is read back to the CPU (such as streaming request buffers), or written to each frame by CPU (such
		 * as indirect arg buffers), and the other GPU doesn't actually care about the data.
		*/
		MultiGPUGraphIgnore		= 1 << 18,
		
		/** Allows buffer to be used as a scratch buffer for building ray tracing acceleration structure,
		 * which implies unordered access. Only changes the buffer alignment and can be combined with other flags.
		**/
		RayTracingScratch = (1 << 19) | UnorderedAccess,

		/** The buffer is a placeholder for streaming, and does not contain an underlying GPU resource. */
		NullResource = 1 << 20,

		/** Buffer can be used as uniform buffer on platforms that do support uniform buffer objects. */
		UniformBuffer = 1 << 21,

		/**
		* EXPERIMENTAL: Allow the buffer to be created as a reserved (AKA tiled/sparse/virtual) resource internally, without physical memory backing.
		* May not be used with Dynamic and other buffer flags that prevent the resource from being allocated in local GPU memory.
		*/
		ReservedResource = 1 << 22,

		// Helper bit-masks
		AnyDynamic = (Dynamic | Volatile),
	};
	ENUM_CLASS_FLAGS(EBufferUsageFlags);
	enum EShaderFrequency : uint8
	{
		SF_Vertex				= 0,
		SF_Mesh					= 1,
		SF_Amplification		= 2,
		SF_Pixel				= 3,
		SF_Geometry				= 4,
		SF_Compute				= 5,
		SF_RayGen				= 6,
		SF_RayMiss				= 7,
		SF_RayHitGroup			= 8,
		SF_RayCallable			= 9,
		SF_WorkGraphRoot		= 10,
		SF_WorkGraphComputeNode	= 11,

		SF_NumFrequencies	= 12,

		// Number of standard shader frequencies for graphics pipeline (excluding compute)
		SF_NumGraphicsFrequencies = 5,

		// Number of standard shader frequencies (including compute)
		SF_NumStandardFrequencies = 6,

		SF_NumBits			= 4,
	};
	static_assert(SF_NumFrequencies <= (1 << SF_NumBits), "SF_NumFrequencies will not fit on SF_NumBits");

	inline bool IsValidGraphicsFrequency(EShaderFrequency InShaderFrequency)
	{
		switch (InShaderFrequency)
		{
		case SF_Vertex:        return true;
#if PLATFORM_SUPPORTS_MESH_SHADERS
		case SF_Mesh:          return true;
		case SF_Amplification: return true;
#endif
		case SF_Pixel:         return true;
		case SF_Geometry:      return true;
		}
		return false;
	}

	inline bool IsComputeShaderFrequency(EShaderFrequency ShaderFrequency)
	{
		switch (ShaderFrequency)
		{
		case SF_Compute:
		case SF_RayGen:
		case SF_RayMiss:
		case SF_RayHitGroup:
		case SF_RayCallable:
			return true;
		}
		return false;
	}
	/** An enumeration of the different CGI reference types. */
	enum ECGIResourceType : uint8
	{
		RRT_None,

		RRT_SamplerState,
		RRT_RasterizerState,
		RRT_DepthStencilState,
		RRT_BlendState,
		RRT_VertexDeclaration,
		RRT_VertexShader,
		RRT_MeshShader,
		RRT_AmplificationShader,
		RRT_PixelShader,
		RRT_GeometryShader,
		RRT_RayTracingShader,
		RRT_ComputeShader,
		RRT_GraphicsPipelineState,
		RRT_ComputePipelineState,
		RRT_RayTracingPipelineState,
		RRT_BoundShaderState,
		RRT_UniformBufferLayout,
		RRT_UniformBuffer,
		RRT_Buffer,
		RRT_Texture,
		// @todo: texture type unification - remove these
		RRT_Texture2D,
		RRT_Texture2DArray,
		RRT_Texture3D,
		RRT_TextureCube,
		// @todo: texture type unification - remove these
		RRT_TextureReference,
		RRT_TimestampCalibrationQuery,
		RRT_GPUFence,
		RRT_RenderQuery,
		RRT_RenderQueryPool,
		RRT_Viewport,
		RRT_UnorderedAccessView,
		RRT_ShaderResourceView,
		RRT_RayTracingAccelerationStructure,
		RRT_RayTracingShaderBindingTable,
		RRT_StagingBuffer,
		RRT_CustomPresent,
		RRT_ShaderLibrary,
		RRT_PipelineBinaryLibrary,
		RRT_ShaderBundle,
		RRT_WorkGraphShader,
		RRT_WorkGraphPipelineState,
		RRT_StreamSourceSlot,
		RRT_ResourceCollection,

		RRT_Num
	};

	/** Describes the dimension of a texture. */
	enum class ETextureDimension : uint8
	{
		Texture2D,
		Texture2DArray,
		Texture3D,
		TextureCube,
		TextureCubeArray
	};

	/** Flags used for texture creation */
	enum class ETextureCreateFlags : uint64
	{
	    None                              = 0,

	    // Texture can be used as a render target
	    RenderTargetable                  = 1ull << 0,
	    // Texture can be used as a resolve target
	    ResolveTargetable                 = 1ull << 1,
	    // Texture can be used as a depth-stencil target.
	    DepthStencilTargetable            = 1ull << 2,
	    // Texture can be used as a shader resource.
	    ShaderResource                    = 1ull << 3,
	    // Texture is encoded in sRGB gamma space
	    SRGB                              = 1ull << 4,
	    // Texture data is writable by the CPU
	    CPUWritable                       = 1ull << 5,
	    // Texture will be created with an un-tiled format
	    NoTiling                          = 1ull << 6,
	    // Texture will be used for video decode
	    VideoDecode                       = 1ull << 7,
	    // Texture that may be updated every frame
	    Dynamic                           = 1ull << 8,
	    // Texture will be used as a render pass attachment that will be read from
	    InputAttachmentRead               = 1ull << 9,
	    /** Texture represents a foveation attachment */
	    Foveation                         = 1ull << 10,
	    // Prefer 3D internal surface tiling mode for volume textures when possible
	    Tiling3D                          = 1ull << 11,
	    // This texture has no GPU or CPU backing. It only exists in tile memory on TBDR GPUs (i.e., mobile).
	    Memoryless                        = 1ull << 12,
	    // Create the texture with the flag that allows mip generation later, only applicable to D3D11
	    GenerateMipCapable ALICE_DEPRECATED(5.5,
			"The GenerateMipCapable flag is no longer used."
			" Use ETextureCreateFlags::UAV to make a texture compatible with compute-based mip generation,"
			" or use ETextureCreateFlags::RenderTargetable for raster-based mip generation.")
			                              = 1ull << 13,
	    // The texture can be partially allocated in fastvram
	    FastVRAMPartialAlloc              = 1ull << 14,
	    // Do not create associated shader resource view, only applicable to D3D11 and D3D12
	    DisableSRVCreation                = 1ull << 15,
	    // Do not allow Delta Color Compression (DCC) to be used with this texture
	    DisableDCC                        = 1ull << 16,
	    // UnorderedAccessView (DX11 only)
	    // Warning: Causes additional synchronization between draw calls when using a render target allocated with this flag, use sparingly
	    // See: GCNPerformanceTweets.pdf Tip 37
	    UAV                               = 1ull << 17,
	    // Render target texture that will be displayed on screen (back buffer)
	    Presentable                       = 1ull << 18,
	    // Texture data is accessible by the CPU
	    CPUReadback                       = 1ull << 19,
	    // Texture was processed offline (via a texture conversion process for the current platform)
	    OfflineProcessed                  = 1ull << 20,
	    // Texture needs to go in fast VRAM if available (HINT only)
	    FastVRAM                          = 1ull << 21,
	    // by default the texture is not showing up in the list - this is to reduce clutter, using the FULL option this can be ignored
	    HideInVisualizeTexture            = 1ull << 22,
	    // Texture should be created in virtual memory, with no physical memory allocation made
	    // You must make further calls to CGIVirtualTextureSetFirstMipInMemory to allocate physical memory
	    // and CGIVirtualTextureSetFirstMipVisible to map the first mip visible to the GPU
	    Virtual                           = 1ull << 23,
	    // Creates a RenderTargetView for each array slice of the texture
	    // Warning: if this was specified when the resource was created, you can't use SV_RenderTargetArrayIndex to route to other slices!
	    TargetArraySlicesIndependently    = 1ull << 24,
	    // Texture that may be shared with DX9 or other devices
	    Shared                            = 1ull << 25,
	    // RenderTarget will not use full-texture fast clear functionality.
	    NoFastClear                       = 1ull << 26,
	    // Texture is a depth stencil resolve target
	    DepthStencilResolveTarget         = 1ull << 27,
	    // Flag used to indicted this texture is a streamable 2D texture, and should be counted towards the texture streaming pool budget.
	    Streamable                        = 1ull << 28,
	    // Render target will not FinalizeFastClear; Caches and meta data will be flushed, but clearing will be skipped (avoids potentially trashing metadata)
	    NoFastClearFinalize               = 1ull << 29,
		/** Texture needs to support atomic operations */
		Atomic64Compatible                = 1ull << 30,
	    // Workaround for 128^3 volume textures getting bloated 4x due to tiling mode on some platforms.
	    ReduceMemoryWithTilingMode        = 1ull << 31,
	    /** Texture needs to support atomic operations */
	    AtomicCompatible                  = 1ull << 33,
		/** Texture should be allocated for external access. Vulkan only */
		External                		  = 1ull << 34,
		/** Don't automatically transfer across GPUs in multi-GPU scenarios.  For example, if you are transferring it yourself manually. */
		MultiGPUGraphIgnore				  = 1ull << 35,
		/**
		* EXPERIMENTAL: Allow the texture to be created as a reserved (AKA tiled/sparse/virtual) resource internally, without physical memory backing. 
		* May not be used with Dynamic and other buffer flags that prevent the resource from being allocated in local GPU memory.
		*/
		ReservedResource                  = 1ull << 37,
		/** EXPERIMENTAL: Used with ReservedResource flag to immediately allocate and commit memory on creation. May use N small physical memory allocations instead of a single large one. */
		ImmediateCommit                   = 1ull << 38,

		/** Don't lump this texture with streaming memory when tracking total texture allocation sizes */
		ForceIntoNonStreamingMemoryTracking = 1ull << 39,

		/** Textures marked with this are meant to be immediately evicted after creation for intentionally crashing the GPU with a page fault. */
		Invalid                           = 1ull << 40,
	};
	ENUM_CLASS_FLAGS(ETextureCreateFlags)
	enum EAsyncComputePriority
	{
		AsyncComputePriority_Default = 0,
		AsyncComputePriority_High,
	};

	/**
	 * Async texture reallocation status, returned by RHIGetReallocateTexture2DStatus().
	 */
	enum ETextureReallocationStatus
	{
		TexRealloc_Succeeded = 0,
		TexRealloc_Failed,
		TexRealloc_InProgress,
	};

	/**
	 * Action to take when a render target is set.
	 */
	enum class ERenderTargetLoadAction : uint8
	{
		// Untouched contents of the render target are undefined. Any existing content is not preserved.
		ENoAction,

		// Existing contents are preserved.
		ELoad,

		// The render target is cleared to the fast clear value specified on the resource.
		EClear,

		Num,
		NumBits = 2,
	};
	/**
	 * Action to take when a render target is unset or at the end of a pass. 
	 */
	enum class ERenderTargetStoreAction : uint8
	{
		// Contents of the render target emitted during the pass are not stored back to memory.
		ENoAction,

		// Contents of the render target emitted during the pass are stored back to memory.
		EStore,

		// Contents of the render target emitted during the pass are resolved using a box filter and stored back to memory.
		EMultisampleResolve,

		Num,
		NumBits = 2,
	};
	/**
	 * Common render target use cases
	 */
	enum class ESimpleRenderTargetMode
	{
		// These will all store out color and depth
		EExistingColorAndDepth,							// Color = Existing, Depth = Existing
		EUninitializedColorAndDepth,					// Color = ????, Depth = ????
		EUninitializedColorExistingDepth,				// Color = ????, Depth = Existing
		EUninitializedColorClearDepth,					// Color = ????, Depth = Default
		EClearColorExistingDepth,						// Clear Color = whatever was bound to the rendertarget at creation time. Depth = Existing
		EClearColorAndDepth,							// Clear color and depth to bound clear values.
		EExistingContents_NoDepthStore,					// Load existing contents, but don't store depth out.  depth can be written.
		EExistingColorAndClearDepth,					// Color = Existing, Depth = clear value
		EExistingColorAndDepthAndClearStencil,			// Color = Existing, Depth = Existing, Stencil = clear

		// If you add an item here, make sure to add it to DecodeRenderTargetMode() as well!
	};

	enum class EClearDepthStencil
	{
		Depth,
		Stencil,
		DepthStencil,
	};

	/**
	 * Hint to the driver on how to load balance async compute work.  On some platforms this may be a priority, on others actually masking out parts of the GPU for types of work.
	 */
	enum class EAsyncComputeBudget
	{
		ELeast_0,			//Least amount of GPU allocated to AsyncCompute that still gets 'some' done.
		EGfxHeavy_1,		//Gfx gets most of the GPU.
		EBalanced_2,		//Async compute and Gfx share GPU equally.
		EComputeHeavy_3,	//Async compute can use most of the GPU
		EAll_4,				//Async compute can use the entire GPU.
	};

	enum class ECGIDescriptorHeapType : uint8
	{
		Standard,
		Sampler,
		RenderTarget,
		DepthStencil,
		Count,
		Invalid = MAX_uint8
	};
	enum class ECGIBindlessConfiguration
	{
		Disabled,
		AllShaders,
		RayTracingShaders,
	};
	enum class EColorSpaceAndEOTF
	{
		EUnknown = 0,

		EColorSpace_Rec709  = 1,		// Color Space Uses Rec 709  Primaries
		EColorSpace_Rec2020 = 2,		// Color Space Uses Rec 2020 Primaries
		EColorSpace_DCIP3   = 3,		// Color Space Uses DCI-P3   Primaries
		EEColorSpace_MASK   = 0xf,

		EEOTF_Linear		= 1 << 4,   // Transfer Function Uses Linear Encoding
		EEOTF_sRGB			= 2 << 4,	// Transfer Function Uses sRGB Encoding
		EEOTF_PQ			= 3 << 4,	// Transfer Function Uses PQ Encoding
		EEOTF_MASK			= 0xf << 4,

		ERec709_sRGB		= EColorSpace_Rec709  | EEOTF_sRGB,
		ERec709_Linear		= EColorSpace_Rec709  | EEOTF_Linear,
	
		ERec2020_PQ			= EColorSpace_Rec2020 | EEOTF_PQ,
		ERec2020_Linear		= EColorSpace_Rec2020 | EEOTF_Linear,
	
		EDCIP3_PQ			= EColorSpace_DCIP3 | EEOTF_PQ,
		EDCIP3_Linear		= EColorSpace_DCIP3 | EEOTF_Linear,
	};

	enum class ECGITransitionCreateFlags
	{
		None = 0,

		// Disables fencing between pipelines during the transition.
		NoFence = 1 << 0,

		// Indicates the transition will have no useful work between the Begin/End calls,
		// so should use a partial flush rather than a fence as this is more optimal.
		NoSplit = 1 << 1,

		BeginSimpleMode
	};
	enum class EResourceTransitionFlags
	{
		None                = 0,

		MaintainCompression = 1 << 0, // Specifies that the transition should not decompress the resource, allowing us to read a compressed resource directly in its compressed state.
		Discard				= 1 << 1, // Specifies that the data in the resource should be discarded during the transition - used for transient resource acquire when the resource will be fully overwritten
		Clear				= 1 << 2, // Specifies that the data in the resource should be cleared during the transition - used for transient resource acquire when the resource might not be fully overwritten

		Last = Clear,
		Mask = (Last << 1) - 1
	};
	enum class ERequestedGPUCrash : uint8
	{
		None = 0,
		Type_Hang = 1 << 0,
		Type_PageFault = 1 << 1,
		Type_PlatformBreak = 1 << 2,
		Type_Assert = 1 << 3,

		Queue_Direct = 1 << 4,
		Queue_Compute = 1 << 5,
	};
	/** Screen Resolution */
	struct FScreenResolutionCGI
	{
		uint32	Width;
		uint32	Height;
		uint32	RefreshRate;
	};

	struct FShaderCodeValidationStride
	{
		uint16 BindPoint;
		uint16 Stride;
	};

	struct FShaderCodeValidationType
	{
		uint16 BindPoint;
		EShaderCodeResourceBindingType Type;
	};

	struct FShaderCodeValidationUBSize
	{
		uint16 BindPoint;
		uint32 Size;
	};
	struct FVertexElement
	{
		uint8 mStreamIndex;
		uint8 mOffset;
		EVertexElementType mEVertexElementType;
		uint8 mAttributeIndex;
		uint16 mStride;
		/**
		 * Whether to use instance index or vertex index to consume the element.  
		 * eg if bUseInstanceIndex is 0, the element will be repeated for every instance.
		 */
		uint16 mbUseInstanceIndex;
		FVertexElement(){}
		FVertexElement(const FVertexElement& inVertexElement)
			:FVertexElement(inVertexElement.mStreamIndex,inVertexElement.mOffset,inVertexElement.mEVertexElementType,inVertexElement.mAttributeIndex,inVertexElement.mStride,inVertexElement.mbUseInstanceIndex)
		{
			
		}
		FVertexElement(uint8 InStreamIndex,uint8 InOffset,EVertexElementType InType,uint8 InAttributeIndex,uint16 InStride,bool bInUseInstanceIndex = false):
			mStreamIndex(InStreamIndex),
			mOffset(InOffset),
			mEVertexElementType(InType),
			mAttributeIndex(InAttributeIndex),
			mStride(InStride),
			mbUseInstanceIndex(bInUseInstanceIndex)
		{}
		bool operator==(const FVertexElement& Other) const
		{
			return (mStreamIndex		== Other.mStreamIndex &&
					mOffset			== Other.mOffset &&
					mEVertexElementType			== Other.mEVertexElementType &&
					mAttributeIndex	== Other.mAttributeIndex &&
					mStride			== Other.mStride &&
					mbUseInstanceIndex == Other.mbUseInstanceIndex);
		}
	};
	typedef std::array<FVertexElement,MaxVertexElementCount> VertexDeclarationElementList;	
    typedef AliceAny RenderProxy;
}